<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <!-- 引入本地Bootstrap5的CSS -->
  <link rel="stylesheet" href="http://115.159.88.63:9090/resources/bootstrap/dist/css/bootstrap.min.css" />
  <!-- 引入本地Bootstrap的图标 -->
  <link rel="stylesheet" href="http://115.159.88.63:9090/resources/bootstrap-icons/font/bootstrap-icons.min.css" />
  <!-- 引入本地elementUi的CSS -->
  <link rel="stylesheet" href="http://115.159.88.63:9090/resources/element-ui/lib/theme-chalk/index.css" />

  <!-- <link rel="stylesheet" href="../../node_modules/bootstrap/dist/css/bootstrap.min.css">
  <link rel="stylesheet" href="../../node_modules/bootstrap-icons/font/bootstrap-icons.min.css"> -->
  <link rel="stylesheet" href="./blog-detail.css">
</head>

<body>

  <div id="app">
    <!-- 引入头部组件 -->
    <header class="navbar bg-dark navbar-dark fixed-top navbar-expand-lg ">
      <!-- 版心部分
          container：指定两端留白版心
      -->
      <nav class="container">
        <!-- logo+个人名称
              navbar-brand：导航栏中的一栏需要加的属性
          -->
        <a class="navbar-brand" href="http://localhost/pages/index/index.html">
          <!-- height="40px"：指定图片高度为40px -->
          <img height="40px" src="../../assets/images/itsource-w.png" alt="源码博客">
        </a>

        <!-- 折叠按钮
              navbar-toggler：代表是导航栏中的折叠按钮
              type="button"：默认button是submit，指定为按钮
              data-bs-toggle="collapse"：用于触发折叠菜单的展开与折叠
              data-bs-target="#navmenu"：指定折叠的目标，通过id选择器指定
          -->
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navmenu">
          <!-- navbar-toggler-icon：指定折叠的图标 -->
          <span class="navbar-toggler-icon"></span>
        </button>

        <!-- 导航部分
              collapse：指定一个折叠标签
              navbar-collapse：代表导航栏中的折叠元素
              justify-content-between：指定折叠元素的对齐方式
              ms-5：指定外边距，距离左边5rem
              id="navmenu"：用于折叠按钮寻找到此折叠元素
          -->
        <div class="collapse navbar-collapse justify-content-between ms-5" id="navmenu">
          <!-- navbar-nav：指定导航栏中的导航 -->
          <ul class="navbar-nav">
            <!-- nav-item：指定导航元素 -->
            <li class="nav-item">
              <!-- nav-link：指定导航链接 -->
              <a class="nav-link" href="http://localhost/pages/index/index.html"><i class="bi bi-house-door">首页</i></a>
            </li>
            <!-- nav-item：指定导航元素 -->
            <li class="nav-item">
              <!-- nav-link：指定导航链接 -->
              <a class="nav-link" href="http://localhost/pages/blogarchives/blog-archives.html"><i
                   class="bi bi-clock-fill">归档</i></a>
            </li>
            <!-- 此处使用的是下拉菜单
                      nav-item：指定导航元素
                      dropdown：指定下拉菜单
                  -->
            <li class="nav-item dropdown">
              <!-- nav-link：指定导航链接
                          dropdown-toggle，data-bs-toggle="dropdown"：指定此元素是下拉菜单标签
                          
                      -->
              <a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">
                <i class="bi bi-blockquote-right">文章分类</i>
              </a>
              <!-- dropdown-menu dropdown-menu-dark：指定下拉菜单内容并设置按钮颜色 -->
              <ul class="dropdown-menu dropdown-menu-dark">
                <li v-for="item in articleTypeCount"><a class="dropdown-item"
                     :href="'http://localhost/pages/blogsort/blog-sort.html?articleTypeId='+item.articleTypeId+'&articleTypeName='+item.articleTypeName">{{item.articleTypeName}}</a>
                </li>
              </ul>
            </li>
            <!-- nav-item：指定导航元素 -->
            <li class="nav-item">
              <!-- nav-link：指定导航链接 -->
              <a class="nav-link" href="http://localhost/pages/blogabout/blog-about.html"><i
                   class="bi bi-person-lines-fill">关于我</i></a>
            </li>
          </ul>

          <!-- 搜索按钮部分：使用的是按钮组
                  navbar-nav：指定导航栏中的导航
              -->
          <div class="navbar-nav">
            <!-- 
                      input-group：指定按钮组
                      input-group-sm：指定按钮组大小
                   -->
          </div>
        </div>


      </nav>
    </header>

    <section style="margin-top: 80px">
      <div class="container">
        <a href="#">
          <img :src="article.articlePic" width="100%" alt="" />
        </a>
      </div>
    </section>

    <section class="mt-3">
      <div class="container">
        <div class="card" style="background-color: white;">
          <div class="card-body">
            <div class="text-center">
              <h2 class="my-4">{{article.articleName}}</h2>
              <p>
                <i class="bi bi-folder2-open opacity-50"></i>
                <span class="card-text articleMsg">{{article.articleTypeObj.typeName}}</span>
                <i class="bi bi-tags opacity-50 ms-2"></i>
                <span class="card-text articleMsg">{{article.articleTag}}</span>
                <i class="bi bi-alarm opacity-50  ms-2"></i>
                <span class="card-text articleMsg">{{article.createTime}}</span>
                <el-link @click="addArticleStarNum"  class="card-link articleMsg ms-2">
                  <i class="bi bi-hand-thumbs-up-fill opacity-50"></i> {{article.articleStarNum}}
                </el-link>
                <i class="bi bi-book-half opacity-50 ms-2"></i>
                <span class="card-text articleMsg">{{article.articleReadCount}}</span>
              </p>
              <hr class="my-4" />
              <p v-html="article.articleContent" class="text-start">
              </p>
            </div>
            <hr class="my-4" />
            <div>
              <h3>相关文章</h3>
              <ul class="list-group list-group-flush mb-3">
                <li v-for="item in articleTag" class="list-group-item" style="border: none;">&bull;
                  <a :href="'./blog-detail.html?articleId='+item.id" class="text-info article">{{item.articleName}}</a>
                </li>

              </ul>


              <div style="background-color: #fafbfc;">
                <div class="d-flex">
                  <img src="../../assets/images/p28.jpg" alt="" width="40px" class="rounded-circle m-2" />
                  <input v-model="commentContent" class="form-control h-75 mt-3" placeholder="请输入评论..." />
                </div>
                <button type="button" @click="submitComment" class="btn btn-primary"
                        style="width: 100px;margin-left: 55px;">发表评论</button>
              </div>

              <hr />

              <div v-for="item in comments">
                <div class="delBtn" @click="deleteComment(item.id)">
                  <i class="bi bi-trash3-fill"></i>
                </div>
                <div>
                  <div class="d-flex">
                    <img src="../../assets/images/p28.jpg" alt="" width="40px" class="rounded-circle m-2" />
                    <div class="mt-1">
                      <span class="text-dark fw-bolder h6">游客:
                        <span>{{item.nickname}}</span>
                      </span>
                      <br />
                      <span>{{item.createTime}}</span>
                    </div>
                  </div>
                  <span style="margin-left: 55px;">{{item.content}}</span>
                  <hr class="my-2" />
                </div>
              </div>
              <!-- my-3【上下外边距1rem】，ps-1【左内边距0.25rem】，pe-4【右内边距1.5rem】，
                      d-flex【开启弹性布局】，justify-content-between【主轴方向两端对齐】 -->
              <div class="my-3 ps-1 pe-4 d-flex justify-content-between">
                <p>转载声明：本博客由波波老师创作。可自由转载、引用，
                  但需署名作者且注明文章出处。如转载至微信公众号，请在文末添加作者微信二维码。
                </p>
                <img src="../../assets/images/CSDN.png" alt="" width="150px" height="130px" />
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  </div>


  <!-- 引入本地Bootstrap5的JS -->
  <script src="http://115.159.88.63:9090/resources/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
  <!-- 引入本地vue.js -->
  <script src="http://115.159.88.63:9090/resources/vue/dist/vue.min.js"></script>
  <!-- 引入本地elementUi的JS -->
  <script src="http://115.159.88.63:9090/resources/element-ui/lib/index.js"></script>
  <!-- 引入本地的axios -->
  <script src="http://115.159.88.63:9090/resources/axios/dist/axios.js"></script>

  <!-- <script src="../../node_modules/vue/dist/vue.min.js"></script>
  <script src="../../node_modules/element-ui/lib/index.js"></script>
  <script src="../../node_modules/jQuery/tmp/jquery.js"></script>
  <script src="../../node_modules/bootstrap/dist/js/bootstrap.bundle.js"></script>
  <script src="../../node_modules/axios/dist/axios.min.js"></script> -->
  <script src="../../assets/js/common.js"></script>

  <script>
    /* 必须要挂载分页栏才会起作用 */
    new Vue({
      el: "#app",
      data() {
        return {
          articleTypeCount: [],
          article: {},
          articleTag: [],
          comments: [],
          commentContent: "",
          articleId: "",
          nickname: "",
        };
      },
      methods: {
        addArticleReadCount() {
          const param = {
            articleId: this.articleId
          }

          this.$http.post("/tourist/redisLike/readAdd", param)
            .then(res => {
              // 对象的解构表达式
              let { msg, code, data } = res.data;

              if (code == "200") {
                this.getArticleById()
                this.$message.success(msg)
              } else {
                this.$message.error(msg);
              }
            })
        },

        // 点赞按钮点击事件处理方法
        addArticleStarNum() {
          const param = {
            articleId: this.articleId,
            userId: this.userId
          }

          this.$http.post("/tourist/redisLike/spot", param)
            .then(res => {
              // 对象的解构表达式
              let { msg, code, data } = res.data;
              if (code == "200") {
                this.getArticleById()
                this.$message.success(msg)
              } else {
                this.$message.error(msg);
              }
            })
        },

        // 点击垃圾桶删除评论事件
        deleteComment(id) {
          this.$http.delete("/tourist/comment/" + id)
            .then(res => {
              // 对象的解构表达式
              let { msg, data, success } = res.data;
              if (success) {
                this.getCommentByArticleId();
                this.$message.success(msg);
              } else {
                this.$message.error(msg);
              }
            })
        },

        // 发表评论的事件
        submitComment() {
          let param = {
            articleId: this.articleId,
            content: this.commentContent,
            nickname: this.nickname
          }
          this.$http.post("/tourist/comment", param)
            .then(res => {
              // 对象的解构表达式
              let { msg, data, success } = res.data;
              if (success) {
                this.getCommentByArticleId();
                this.$message.success(msg);
                this.commentContent = "";
              } else {
                this.$message.error(msg);
              }
            })
        },
        getArticleTypeCount() {
          this.$http.get("/tourist/article/articleTypeCountVo")
            .then(res => {
              // 对象的解构表达式
              let { msg, data, success } = res.data;
              if (success) {
                this.articleTypeCount = data;
              } else {
                this.$message.error(msg);
              }
            })
        },
        getArticleById() {
          this.$http.get("/tourist/article/articleById/" + this.articleId)
            .then(res => {
              // 对象的解构表达式
              let { msg, data, success } = res.data;
              if (success) {
                this.article = data;
              } else {
                this.$message.error(msg);
              }
            })
        },
        getArticleByTag() {
          this.$http.get("/tourist/article/articleByTag/" + this.articleId)
            .then(res => {
              // 对象的解构表达式
              let { msg, data, success } = res.data;
              if (success) {
                this.articleTag = data;
              } else {
                this.$message.error(msg);
              }
            })
        },
        getCommentByArticleId() {
          this.$http.get("/tourist/comment/" + this.articleId)
            .then(res => {
              // 对象的解构表达式
              let { msg, data, success } = res.data;
              if (success) {
                this.comments = data;
              } else {
                this.$message.error(msg);
              }
            })
        },
        createUuid() {
          var s = [];
          var hexDigits = "0123456789abcdefghi";
          for (var i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
          }
          s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
          s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
          s[8] = s[13] = s[18] = s[23] = "-";

          var uuid = s.join("");
          return uuid;
        },


        getIPs(callback) {
          var ip_dups = {};
          var RTCPeerConnection = window.RTCPeerConnection
            || window.mozRTCPeerConnection
            || window.webkitRTCPeerConnection;
          var useWebKit = !!window.webkitRTCPeerConnection;
          var mediaConstraints = {
            optional: [{ RtpDataChannels: true }]
          };
          // 这里就是需要的ICEServer了
          var servers = {
            iceServers: [
              { urls: "stun:stun.services.mozilla.com" },
              { urls: "stun:stun.l.google.com:19302" },
            ]
          };
          var pc = new RTCPeerConnection(servers, mediaConstraints);
          function handleCandidate(candidate) {
            var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/
            var hasIp = ip_regex.exec(candidate)
            if (hasIp) {
              var ip_addr = ip_regex.exec(candidate)[1];
              if (ip_dups[ip_addr] === undefined)
                callback(ip_addr);
              ip_dups[ip_addr] = true;
            }
          }
          // 网络协商的过程
          pc.onicecandidate = function (ice) {
            if (ice.candidate) {
              handleCandidate(ice.candidate.candidate);
            }
          };
          pc.createDataChannel("");
          //创建一个SDP(session description protocol)会话描述协议 是一个纯文本信息 包含了媒体和网络协商的信息
          pc.createOffer(function (result) {
            pc.setLocalDescription(result, function () { }, function () { });
          }, function () { });
          setTimeout(function () {
            var lines = pc.localDescription.sdp.split('\n');
            lines.forEach(function (line) {
              if (line.indexOf('a=candidate:') === 0)
                handleCandidate(line);
            });
          }, 1000);
        }
      },
      mounted() {
        // 1.获取到用户的nickname
        let nickname = localStorage.getItem("nickname");
        if (nickname) {
          this.nickname = nickname;
        } else {
          this.nickname = this.createUuid();
          localStorage.setItem("nickname", this.nickname);
        }

        // 2.获取到文章id
        let urlArr = location.href.split("=");
        let articleId = urlArr[urlArr.length - 1];
        this.articleId = articleId;
        this.getArticleTypeCount();
        this.getArticleById();
        this.getArticleByTag();
        this.getCommentByArticleId();

        this.getIPs((ip) => {
          const ips = ip.split(".")
          this.userId = ips[0] + ips[1] + ips[2] + ips[3]
        })
        this.addArticleReadCount()

      },
    })
  </script>

</body>

</html>